/*!
  \file
  Header file for an HHV on the CPU where the data are aligned
*/

#ifndef SCIGPU_HHV_HHVOLUME_ALIGNED_HPP
#define SCIGPU_HHV_HHVOLUME_ALIGNED_HPP

#include <vector>
#include <cstring>

#include "hhvolume.hpp"
#include "objectconvertor.hpp"

#include "alignedallocator.hpp"

namespace SciGPU {
  namespace HHV {

    //! Hypervolume with aligned data
    template<typename T, unsigned int nDims, size_t alignment = 16>
    class HHVolumeAligned : public HHVolume<T,nDims> {
    public:
      //! Make convertor type available
      typedef ObjectConvertor< HHVolumeAligned<T,nDims,alignment>,
			       HHVolume<T,nDims> > convertor;

      //! Constructor with buffer
      HHVolumeAligned( const BufferObject<T>& buff = SimpleBuffer<T>() )
        : HHVolume<T,nDims>(buff),
          data() {};

      //! Destructor
      virtual ~HHVolumeAligned( void ) {};


      // -------------------------------
  
      //! Send data to the internal vector
      virtual void Send( void ) {
        memcpy( &this->data[0], this->buffer->start(), this->hyxels() * sizeof(T) );
      }

      //! Fetch data from internal vector
      virtual void Recv( void ) const {
        memcpy( this->buffer->start(), &this->data[0], this->hyxels() * sizeof(T) );
      }

      // -------------------------------

      //! Access data (const)
      virtual const T* start( void ) const {
        return( &(this->data[0]) );
      }

      //! Access data
      virtual T* start( void ) {
        return( &(this->data[0]) );
      }

    protected:
      //! The actual data on the CPU
      std::vector< T, aligned_allocator<T,alignment> > data;

      virtual void AllocateDevice( const DimensionObject<nDims>& myDims ) {
        this->data.resize( myDims.hyxels() );
      }

    private:

    };

  }
}


#endif
